#include "Material.h"

/************************************************
/*				Public
/************************************************/

    /************************************************
    /*				Constructors
    /************************************************/

        Material::Material(){
            m_VertexTemplate = new VertexTemplate();
        }

    /************************************************
    /*				Methods
    /************************************************/

        void Material::Use(){
            m_Program->Use();
            SendSharedUniforms();
            BindAttributes();
        }


        void Material::AddNewSharedUniform(Uniform * uni){
            m_SharedUniform.push_back(uni);
        }

        void Material::AddNewUniform(Uniform *f){
            m_Uniforms.push_back(f);
        }

        void Material::AttachTo(Entity *entity){
            entity->m_Material=this;
            for(int i=0; i< m_Uniforms.size();i++){
                entity->m_Uniforms.push_back(new UniformMat4(m_Uniforms.at(i)->m_Name,
                                                             m_Uniforms.at(i)->m_Id
                                                             ));

            }
        }

        void Material::GetLocations(){
            GetAttribLocations();
            GetUniformLocation();
        }

    /************************************************
    /*				Get/Set
    /************************************************/

        GLSLProgram &   Material::Program(){
            return * m_Program;
        }

        void Material::Program(GLSLProgram &program){
            m_Program=&program;
        }

        VertexTemplate & Material::SetVertexTemplate(){
            return *m_VertexTemplate;
        }

        void Material::SetVertexTemplate(VertexTemplate & vt){
            m_VertexTemplate=&vt;
        }

/************************************************
/*				Private
/************************************************/

    /************************************************
    /*				Methods
    /************************************************/

    void Material::GetAttribLocations(){
        for(int i=0; i< m_VertexTemplate->attributeCount();i++){
            m_VertexTemplate->attribute(i).m_Id=glGetAttribLocation(m_Program->m_GLID,  m_VertexTemplate->attribute(i).name().c_str());
        }
    }

    void Material::GetUniformLocation(){
        for(int i=0; i< m_SharedUniform.size();i++){
            m_SharedUniform.at(i)->m_Id   = glGetUniformLocation(m_Program->m_GLID, m_SharedUniform.at(i)->m_Name.c_str());

        }
        for(int i=0; i< m_Uniforms.size();i++){
            m_Uniforms.at(i)->m_Id        = glGetUniformLocation(m_Program->m_GLID, m_Uniforms.at(i)->m_Name.c_str());
        }
    }

     void Material::SendSharedUniforms(){
        for(int i=0; i< m_SharedUniform.size(); i++){
            m_SharedUniform.at(i)->Send();
        }
    }

    void Material::BindAttributes(){
        for(int i=0; i< m_VertexTemplate->attributeCount();i++){
            glEnableVertexAttribArray(m_VertexTemplate->attribute(i).id());
            glVertexAttribPointer(m_VertexTemplate->attribute(i).id(),4,GL_FLOAT, GL_FALSE,
                                  ((m_VertexTemplate->attribute(i).size()*4))*sizeof(float),
                                  (void*)+(m_VertexTemplate->attribute(i).offset()*4));

           // qDebug()<<" "<<m_VertexTemplate->attribute(i).name().c_str()<<" "<<m_VertexTemplate->attribute(i).id();
        }
    }

    GLuint Material::IdProgram(){
        return m_Program->m_GLID;
    }
